package com.xiaoye.qbproject.service.impl;

import cn.hutool.core.io.IORuntimeException;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hankcs.hanlp.HanLP;
import com.xiaoye.qbproject.config.ServerConfig;
import com.xiaoye.qbproject.config.XiaoYeConfig;
import com.xiaoye.qbproject.domain.DataImport;
import com.xiaoye.qbproject.domain.QbSubject;
import com.xiaoye.qbproject.domain.QbSubjectArticle;
import com.xiaoye.qbproject.domain.model.QbSubjectArticleExcelMode;
import com.xiaoye.qbproject.domain.wiki.QbSubjectWiki;
import com.xiaoye.qbproject.exception.ServiceException;
import com.xiaoye.qbproject.listener.QbSubjectArticleExcelModeListener;
import com.xiaoye.qbproject.listener.QbSubjectWikiExcelModeListener;
import com.xiaoye.qbproject.mapper.DataImportMapper;
import com.xiaoye.qbproject.service.*;
import lombok.extern.slf4j.Slf4j;
import org.codehaus.plexus.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.stream.Collectors;

import static com.xiaoye.qbproject.constant.Constants.RESOURCE_PREFIX;

/**
 * @author Administrator
 * @description 针对表【DATA_IMPORT(数据导入)】的数据库操作Service实现
 * @createDate 2025-02-28 14:44:29
 */
@Slf4j
@Service
public class DataImportServiceImpl extends ServiceImpl<DataImportMapper, DataImport>
        implements DataImportService {
    @Autowired
    ZipService zipService;
    @Autowired
    private QbSubjectService qbSubjectService;
    @Autowired
    private QbSubjectArticleService qbSubjectArticleService;
    @Autowired
    private ServerConfig serverConfig;
    @Autowired
    private QbSubjectWikiService qbSubjectWikiService;

    @Override
    public void parseData(String id) {
        // 获取文件信息
        DataImport dataImport = this.getById(id);
        if (dataImport == null) {
            throw new ServiceException("数据导入信息不存在");
        }
        String fileName = dataImport.getFileName();
        if (StringUtils.isBlank(fileName) || (!fileName.contains("wiki") && !fileName.contains("article"))) {
            throw new ServiceException("请检查zip文件,是否为采集系统导出");
        }

        // /profile/upload/2025/02/28/开增益_20250228151337A001.gif
        String filePath = dataImport.getFilePath();
/*        if (!filePath.endsWith(".zip")) {
            throw new ServiceException("文件不是zip格式");

        }*/
        if (!filePath.startsWith(RESOURCE_PREFIX)) {
            throw new ServiceException("文件路径不正确");
        }
        // filePath 去除 RESOURCE_PREFIX 前缀
        filePath = filePath.substring(RESOURCE_PREFIX.length());
        filePath = XiaoYeConfig.getProfile() + filePath;
        log.info("filePath:{}", filePath);


        // 解压缩文件
        List<String> unZipFilePathList;

        try {
            unZipFilePathList = zipService.extractAllFilesFromZip(filePath);
        } catch (IORuntimeException e) {
            log.error("文件不存在", e);
            throw new ServiceException("文件不存在,请检查文件是否上传或存储路径是否正确");
        } catch (ServiceException e) {
            log.error("解压缩文件失败", e);
            throw new ServiceException("解压缩文件失败");
        }

        // 获取excel 文件
        String excel = unZipFilePathList.stream().filter(e -> e.endsWith(".xlsx") || e.endsWith(".xls")).findFirst().get();
        // 使用 easyexcel 解析数据
        // 读取excel 文件
        File excelFile = new File(excel);
        if (!excelFile.exists()) {
            throw new ServiceException("excel文件不存在");
        }
        if (excelFile.getName().contains("wiki")) {
            // 维基百科
            QbSubjectWikiExcelModeListener listener = new QbSubjectWikiExcelModeListener();
            EasyExcel.read(excelFile, QbSubjectWiki.class, listener).sheet().doRead();
            List<QbSubjectWiki> wikiList = listener.getDataList();
            for (QbSubjectWiki wiki : wikiList) {
                wiki.setSubjectId(matchSubjectId(wiki, qbSubjectService.list(Wrappers
                        .lambdaQuery(QbSubject.class)
                        .eq(QbSubject::getType, "wiki")))
                );
                // TODO 图片
                //wiki.setContent(handleContent(articleExcelMode, unZipFilePathList));

            }
            log.info("需要导入的维基百科数据:{}", wikiList);
            // 保存数据
            qbSubjectWikiService.saveOrUpdateBatch(wikiList);
        } else {
            // 创建监听器
            QbSubjectArticleExcelModeListener listener = new QbSubjectArticleExcelModeListener();
            EasyExcel.read(excelFile, QbSubjectArticleExcelMode.class, listener).sheet().doRead();
            // 获取解析后的数据
            List<QbSubjectArticleExcelMode> dataList = listener.getDataList();
            // 解析数据
            List<QbSubjectArticle> subjectArticleList = new ArrayList<>();
            // 获取所有专题
            List<QbSubject> subjectList = qbSubjectService.list(Wrappers
                    .lambdaQuery(QbSubject.class)
                    .eq(QbSubject::getType, "news")
            );
            for (QbSubjectArticleExcelMode articleExcelMode : dataList) {
                QbSubjectArticle subjectArticle = new QbSubjectArticle();
                subjectArticle.setId(articleExcelMode.getId());
                subjectArticle.setTitle(articleExcelMode.getTitle());
                subjectArticle.setContent(handleContent(articleExcelMode, unZipFilePathList));
                subjectArticle.setCover(articleExcelMode.getCover());
                subjectArticle.setKeywords(articleExcelMode.getKeywords());
                subjectArticle.setRemark(articleExcelMode.getRemark());
                subjectArticle.setSource(articleExcelMode.getSource());
                // 这里需要匹配 关键词
                subjectArticle.setSubjectId(matchSubjectId(articleExcelMode, subjectList));
                subjectArticle.setCreateTime(new Date());
                subjectArticle.setUpdateTime(new Date());
                subjectArticleList.add(subjectArticle);
            }
            log.info("需要导入的文章数据:{}", subjectArticleList);
            // 保存数据
            qbSubjectArticleService.saveOrUpdateArtBatch(subjectArticleList);
        }

    }

    private String matchSubjectId(QbSubjectArticleExcelMode articleExcelMode, List<QbSubject> subjectList) {
        String keywords = articleExcelMode.getKeywords();
        // 文章关键词

        String subjectId = null;
        for (QbSubject qbSubject : subjectList) {
            String subjectKeywords = qbSubject.getKeywords();
            if (hasMatchingKeywordsOfSplit(keywords, subjectKeywords)) {
                log.info("匹配到专题:{}:导入文章:{}========专题关键词:{}", qbSubject.getName(), keywords, subjectKeywords);
                subjectId = qbSubject.getId();
                break;
            }
        }

        return subjectId;
    }

    private String matchSubjectId(QbSubjectWiki wiki, List<QbSubject> subjectList) {
        String keywords = wiki.getKeywords();
        // 文章关键词

        String subjectId = null;
        for (QbSubject qbSubject : subjectList) {
            String subjectKeywords = qbSubject.getKeywords();
            if (hasMatchingKeywordsOfSplit(keywords, subjectKeywords)) {
                log.info("匹配到专题:{}:导入维基百科:{}========专题关键词:{}", qbSubject.getName(), keywords, subjectKeywords);
                subjectId = qbSubject.getId();
                break;
            }
        }

        return subjectId;
    }

    private String handleContent(QbSubjectArticleExcelMode articleExcelMode, List<String> unZipFilePathList) {
        String content = articleExcelMode.getContent();
        String contentImages = articleExcelMode.getContentImages();
        if (StringUtils.isBlank(contentImages)) {
            return content;
        }
        // 字符串 用回车或者逗号分割
        String[] imagePaths = contentImages.split("[\\n,]+");
        for (String imageName : imagePaths) {
            String imagePath = unZipFilePathList.stream().filter(e -> e.endsWith(imageName)).findFirst().get();
            log.info("imagePath:{}", imagePath);
            if (StringUtils.isBlank(imagePath)) {
                continue;
            }
            String url = serverConfig.getUrl() + RESOURCE_PREFIX + imagePath.substring(XiaoYeConfig.getProfile().length());
            url = url.replace("\\", "/");
            log.info("imageUrl:{}", url);
            content += "<img src='" + url + "'/>";
        }


        return content;
    }

    /**
     * 判断两组逗号拼接的字符串是否有匹配的关键词（使用 HanLP 分词）
     *
     * @param group1 第一组逗号拼接的字符串
     * @param group2 第二组逗号拼接的字符串
     * @return 如果有匹配的关键词返回 true，否则返回 false
     */
    public static boolean hasMatchingKeywords(String group1, String group2) {
        // 使用 HanLP 对两组字符串进行分词
        List<String> keywords1 = HanLP.segment(group1).stream()
                .map(term -> term.word).collect(Collectors.toList()); // 提取分词结果中的词语

        // 将第二组关键词放入 Set 中，方便快速查找
        Set<String> keywordSet2 = HanLP.segment(group2).stream()
                .map(term -> term.word).collect(Collectors.toSet());

        // 遍历第一组关键词，检查是否在第二组中存在
        for (String keyword : keywords1) {
            if (keywordSet2.contains(keyword)) {
                return true; // 找到匹配的关键词
            }
        }

        return false; // 没有匹配的关键词
    }

    /**
     * 判断两组逗号拼接的字符串是否有匹配的关键词
     *
     * @param group1 第一组逗号拼接的字符串
     * @param group2 第二组逗号拼接的字符串
     * @return 如果有匹配的关键词返回 true，否则返回 false
     */
    public static boolean hasMatchingKeywordsOfSplit(String group1, String group2) {
        // 拆分字符串为关键词数组
        String[] keywords1 = group1.split(",");
        String[] keywords2 = group2.split(",");

        // 将第二组关键词放入 Set 中，方便快速查找
        Set<String> keywordSet2 = new HashSet<>(Arrays.asList(keywords2));

        // 遍历第一组关键词，检查是否在第二组中存在
        for (String keyword : keywords1) {
            if (keywordSet2.contains(keyword)) {
                return true; // 找到匹配的关键词
            }
        }

        return false; // 没有匹配的关键词
    }
}




